// Author: Mohamed Abdel Hakim
calendar = {
    month_names: ["January","February","March","April","May","June","July","August","September","October","November","December"],
    weekdays: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
    month_days: [31,28,31,30,31,30,31,31,30,31,30,31],
    //Get today's date - year, month, day and date
    today : new Date(),
    opt : {},
    data: [],
    //Functions
    /// short hand to print HTML elements
    wrt:function(txt) {
        this.data.push(txt);
    },
    // function to adjust the style and position of the div when it's called
    getStyle: function(ele, property){
        if (ele.currentStyle) {
            var value = ele.currentStyle[property]||ele.currentStyle[alt_property_name];
        }
        //Some properties are special cases
        else if(property == "width" && isNaN(value)) value = ele.clientWidth || ele.offsetWidth;
        else if(property == "height" && isNaN(value)) value = ele.clientHeight || ele.offsetHeight;
        return value;
    },
    getPosition:function(ele) {
        var x = 0;
        var y = 0;
        while (ele) {
            x += ele.offsetLeft;
            y += ele.offsetTop;
            ele = ele.offsetParent;
        }
        var xy = new Array(x,y);
        return xy;
    },
    // Called when the user clicks on a date in the calendar.
    selectDate:function(year,month,day) {
        var ths = _calendar_active_instance;
        var elem=document.getElementById(this.opt["input"]); // MySQL Date format
        elem.value = year + "-" + month + "-" + day;
        $(elem).trigger("change");
        this.hideCalendar();
    },
    // Creates a calendar with the date given in the argument as the selected date.
    makeCalendar:function(year, month, day) {
        year = parseInt(year);
        month= parseInt(month);
        day= parseInt(day);
        //Display the table
        this.wrt("<table class='calendar'>");
        this.wrt("<th colspan='10' class='calendar-title' style='text-align:center'><select align='center' style='width:fit-content;' name='calendar-month' class='calendar-month' onChange='calendar.makeCalendar("+year+",this.value);'>");
        for(var i in this.month_names) {
            this.wrt("<option value='"+i+"'");
            if(i == month) this.wrt(" selected='selected'");
            this.wrt(">"+this.month_names[i]+"</option>");
        }
        this.wrt("</select>");
        this.wrt("<select style='width:fit-content;' name='calendar-year' class='calendar-year' onChange='calendar.makeCalendar(this.value, "+month+");'>");
        var current_year = 2012;
        for(var i=current_year; i<current_year+20; i++) {
            this.wrt("<option value='"+i+"'")
            if(i == year) this.wrt(" selected='selected'");
            this.wrt(">"+i+"</option>");
        }
        this.wrt("</select></th>");
        this.wrt("<tr class='header'>");
        for(var weekday=0; weekday<7; weekday++) this.wrt("<td>"+this.weekdays[weekday]+"</td>");
        this.wrt("</tr>");
        //Get the first day of this month
        var first_day = new Date(year,month,1);
        var start_day = first_day.getDay();
        var d = 1;
        var flag = 0;
        var days_in_this_month = this.month_days[month];
        //Create the calender
        for(var i=0;i<=7;i++) {
            if(w >= days_in_this_month) break;
            this.wrt("<tr>");
            for(var j=0;j<7;j++) {
                if(d > days_in_this_month) flag=0; //If the days has overshooted the number of days in this month, stop writing
                else if(j >= start_day && !flag) flag=1;//If the first day of this month has come, start the date writing
                if(flag) {
                    var w = d, mon = month+1;
                    if(w < 10)	w	= "0" + w;
                    if(mon < 10)mon = "0" + mon;
                    var class_name = '';
                    this.wrt("<td onclick='javascript:calendar.selectDate(\""+year+"\",\""+mon+"\",\""+w+"\")'class='days"+class_name+"'><a href='javascript:calendar.selectDate(\""+year+"\",\""+mon+"\",\""+w+"\")'>"+w+"</a></td>");
                    d++;
                } else {
                    this.wrt("<td class='days'></td>");
                }
            }
            this.wrt("</tr>");
        }
        this.wrt("<th style='border:0;' colspan='10'><input type='button' value='Cancel' class='calendar-cancel' onclick='calendar.hideCalendar();' /></th>");
        this.wrt("</table>");
        document.getElementById(this.opt['calendar']).innerHTML = this.data.join("");
        this.data = [];
    },
    // Display the calendar
    showCalendar: function() {
        var input = document.getElementById(this.opt['input']);
        //Position the div in the correct location.
        var div = document.getElementById(this.opt['calendar']);
        var xy = this.getPosition(input);
        var width = parseInt(this.getStyle(input,'width'));
        var hpos=$(input).offset().left+$(input).width()-$(window).scrollLeft();
        if(($(window).width()-hpos)<$(div).width())
            $(div).css("left",hpos-$(div).width());
        else
            $(div).css("left", hpos-175);
        //div.style.left=(xy[0]+width+10)+"px";
        var vpos=$(input).offset().top-$(window).scrollTop();
        if(($(window).height()-vpos)<200)
            div.style.top=(vpos-200)+"px";
        else
            div.style.top=vpos+ 20 + "px";
        // Show the calendar with the date in the input as the selected date
        var existing_date = new Date();
        var the_year = existing_date.getYear();
        if(the_year < 1900) the_year += 1900;
        this.makeCalendar(the_year, existing_date.getMonth(), existing_date.getDate());
        document.getElementById(this.opt['calendar']).style.display = "block";
        _calendar_active_instance = this;
    },
    /// Hides the currently show calendar.
    hideCalendar: function(instance) {
        _calendar_active_instance = this;
        var active_calendar_id = "";
        if(instance) active_calendar_id = instance.opt['calendar'];
        else active_calendar_id = _calendar_active_instance.opt['calendar'];
        if(active_calendar_id) document.getElementById(active_calendar_id).style.display = "none";
        _calendar_active_instance = {};
    },
    /// Setup a text input box to be a calendar box.
    set: function(input_id) {
        var input = document.getElementById(input_id);
        if(!input) return; //If the input field is not there, exit.
        if(!this.opt['calendar']) this.init();
        var ths = this;
        ths.opt['input'] = input.id;
        ths.showCalendar();
    },
    // Will be called once when the first input is set.
    init: function() {
        if(!this.opt['calendar'] || !document.getElementById(this.opt['calendar'])) {
            var div = document.createElement('div');
            if(!this.opt['calendar']) this.opt['calendar'] = 'calender_div_';
            div.setAttribute('id',this.opt['calendar']);
            div.className="calendar-box";
            document.getElementsByTagName("body")[0].insertBefore(div,document.getElementsByTagName("body")[0].firstChild);
        }
    }
}